<?php


namespace BoojasrFramework\Command;

use BoojasrFramework\Kernel;
use BoojasrFramework\KernelInterface;
use BoojasrFramework\Service\DoctrineManageService;
use BoojasrFramework\ServicesContainer\EventDispatcher\EventDispatcherInterface;
use BoojasrFramework\ServicesContainer\ServicesClassFactory;
use Doctrine\ORM\Tools\Console\ConsoleRunner;
use Doctrine\ORM\Tools\Console\EntityManagerProvider\SingleManagerProvider;
use Symfony\Component\Console\Application as SymfonyApplication;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class Application extends SymfonyApplication
{
    /**
     * @var KernelInterface
     */
    private $kernel;

    private $commandsRegistered;

    private $dispatcher;

    public function __construct(KernelInterface $kernel)
    {
        $this->kernel = $kernel;

        parent::__construct('boojasr', Kernel::VERSION);

        $inputDefinition = $this->getDefinition();
        $inputDefinition->addOption(new InputOption('--env', '-e', InputOption::VALUE_REQUIRED, '环境名称', $kernel->getEnv()));
        $inputDefinition->addOption(new InputOption('--no-debug', null, InputOption::VALUE_NONE, '关闭调试模式'));
    }

    /**
     * @return KernelInterface
     */
    public function getKernel(): KernelInterface
    {
        return $this->kernel;
    }

    /**
     * Runs the current application.
     *
     * @return int 0 if everything went fine, or an error code
     * @throws \Throwable
     */
    public function doRun(InputInterface $input, OutputInterface $output)
    {
        $this->registerCommands();

        $this->setDispatcherImpl($this->kernel->getContainer()->get('event_dispatcher'));

        return parent::doRun($input, $output);
    }

    public function setDispatcherImpl(EventDispatcherInterface $dispatcher){
        $this->dispatcher = $dispatcher;
    }

    public function registerCommands(){
        if ($this->commandsRegistered) {
            return;
        }
        $this->kernel->boot();
        $this->commandsRegistered = true;

        $command_service = ServicesClassFactory::$container->get("command_service");
        $commands = $command_service->getCommands();
        //add ORM commands
        ConsoleRunner::addCommands($this,$this->getSingleManagerProvider());
        $this->addCommands($commands);
    }

    public function add(Command $command): ?Command
    {
        $this->registerCommands();

        return parent::add($command);
    }

    public function getSingleManagerProvider(){
        /** @var DoctrineManageService $doctrine */
        $doctrine = ServicesClassFactory::$container->get("doctrine");
        $doctrine->setIsDevMode(true);
        $entityManager = $doctrine->getEntityManage();
        return new SingleManagerProvider($entityManager);
    }

}
